home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
termsorc.lha
/
Extras
/
Source
/
term-source.lha
/
termMemory.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-26
|
9KB
|
421 lines
/*
** termMemory.c
**
** Memory management routines
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
// Main memory pool puddle size
#define PUDDLE_SIZE 32768
// Memory allocation data
STATIC struct SignalSemaphore MemorySemaphore;
STATIC APTR MemoryPool;
// Prototypes for pools.lib
APTR __asm AsmCreatePool(register __d0 ULONG MemFlags,register __d1 ULONG PuddleSize,register __d2 ULONG ThreshSize,register __a6 struct ExecBase *SysBase);
VOID __asm AsmDeletePool(register __a0 APTR PoolHeader,register __a6 struct ExecBase *SysBase);
APTR __asm AsmAllocPooled(register __a0 APTR PoolHeader, register __d0 ULONG Size,register __a6 struct ExecBase *SysBase);
VOID __asm AsmFreePooled(register __a0 APTR PoolHeader,register __a1 APTR Memory,register __d0 ULONG MemSize,register __a6 struct ExecBase *SysBase);
// Diagnostic data
typedef char (* __asm SegTrack(register __a0 ULONG Address,register __a1 ULONG *SegNum,register __a2 ULONG *Offset));
struct SegSem
{
struct SignalSemaphore seg_Semaphore;
SegTrack *seg_Find;
};
struct FirewallInfo
{
ULONG Checksum;
ULONG Address;
ULONG TotalSize;
ULONG ReturnAddress;
ULONG Size;
ULONG FillByte;
ULONG FirePre;
ULONG FirePost;
};
STATIC LONG FirewallPre = 0,FirewallPost = 0;
STATIC ULONG FillByte = 1;
STATIC LONG Smallest = -1,Largest = -1;
/* MemorySetup():
*
* Set up the main memory pool.
*/
BOOLEAN
MemorySetup()
{
BOOL DosOpen = FALSE;
if(!DOSBase)
{
if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
DosOpen = TRUE;
}
if(DOSBase)
{
UBYTE LocalBuffer[256];
if(GetVar("TERMPREALLOC",LocalBuffer,256,NULL) > 0)
{
if(StrToLong(LocalBuffer,&FirewallPre) > 0)
{
if(FirewallPre < 16)
FirewallPre = 16;
FirewallPost = 16;
if(GetVar("TERMPOSTALLOC",LocalBuffer,256,NULL) > 0)
{
if(StrToLong(LocalBuffer,&FirewallPre) <= 0)
FirewallPost = 16;
}
FirewallPre = (FirewallPre + 15) & ~15;
FirewallPost = (FirewallPost + 15) & ~15;
if(!FirewallPost)
FirewallPost = 16;
}
else
FirewallPost = 0;
}
if(DosOpen)
{
CloseLibrary((struct Library *)DOSBase);
DOSBase = NULL;
}
}
InitSemaphore(&MemorySemaphore);
if(MemoryPool = AsmCreatePool(MEMF_PUBLIC | MEMF_ANY,PUDDLE_SIZE,PUDDLE_SIZE,SysBase))
return(TRUE);
else
return(FALSE);
}
/* MemoryCleanup():
*
* Clean up the main memory pool.
*/
VOID
MemoryCleanup()
{
if(Smallest != -1)
{
kprintf("term stats: smallest allocation was %ld bytes\n",Smallest);
Smallest = -1;
}
if(Largest != -1)
{
kprintf("term stats: largest allocation was %ld bytes\n",Largest);
Largest = -1;
}
if(MemoryPool)
{
AsmDeletePool(MemoryPool,SysBase);
MemoryPool = NULL;
}
}
/* FreeVecPooled(APTR Memory):
*
* Free a memory chunk.
*/
VOID __asm
FreeVecPooledLocal(register __a0 APTR Memory,register __a1 ULONG ReturnAddress)
{
if(Memory && MemoryPool)
{
ULONG *Data = (ULONG *)Memory;
ObtainSemaphore(&MemorySemaphore);
if(FirewallPre)
{
struct FirewallInfo *Info;
ULONG Sum,*Thing;
WORD i;
Info = (struct FirewallInfo *)(((ULONG)Memory) - (sizeof(struct FirewallInfo) + FirewallPre));
for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
Sum += Thing[i];
if(Info -> Checksum == ~Sum && Memory == (APTR)Info -> Address)
{
UBYTE *Data;
LONG i;
BOOL AllocationProblem = FALSE;
Data = (UBYTE *)Info -> FirePre;
for(i = 0 ; i < FirewallPre ; i++)
{
if(Data[i] != Info -> FillByte)
{
LONG j;
AllocationProblem = TRUE;
kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed before, FillByte %02lx:",Memory,Info -> Size,FirewallPre - i,Info -> FillByte);
Data = &Data[i];
for(j = 0 ; j < FirewallPre - i ; j++)
{
if(!(j & 7))
kprintf("\n %08lx: ",&Data[j]);
kprintf("%02lx ",Data[j]);
}
kprintf("\n");
break;
}
}
Data = (UBYTE *)Info -> FirePost;
for(i = FirewallPost - 1 ; i >= 0 ; i--)
{
if(Data[i] != Info -> FillByte)
{
LONG j;
Data = (UBYTE *)Info -> FirePost;
if(AllocationProblem)
kprintf(" %ld bytes trashed after:",i + 1);
else
kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed after, FillByte 0x%02lx:",Memory,Info -> Size,i + 1,Info -> FillByte);
AllocationProblem = TRUE;
for(j = 0 ; j <= i ; j++)
{
if(!(j & 7))
kprintf("\n %08lx: ",&Data[j]);
kprintf("%02lx ",Data[j]);
}
kprintf("\n");
break;
}
}
if(AllocationProblem)
{
struct SegSem *SegTracker;
Forbid();
if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
{
char LocalBuffer[256];
ULONG Segment,Offset;
char *Name;
kprintf("\n");
if(Name = (*SegTracker -> seg_Find)(Info -> ReturnAddress,&Segment,&Offset))
{
CopyMem(Name,LocalBuffer,255);
LocalBuffer[255] = 0;
kprintf(" Alloc by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset);
}
if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
{
CopyMem(Name,LocalBuffer,255);
LocalBuffer[255] = 0;
kprintf(" Free by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset);
}
}
Permit();
}
AsmFreePooled(MemoryPool,Info,Info -> TotalSize,SysBase);
}
else
{
struct SegSem *SegTracker;
Forbid();
if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
{
char LocalBuffer[256];
ULONG Segment,Offset;
char *Name;
if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
{
CopyMem(Name,LocalBuffer,255);
LocalBuffer[255] = 0;
kprintf(" Bogus free from 0x%08lx by |%s| %lx:%lx\n",Memory,LocalBuffer,Segment,Offset);
}
}
Permit();
}
}
else
AsmFreePooled(MemoryPool,&Data[-1],Data[-1],SysBase);
ReleaseSemaphore(&MemorySemaphore);
}
}
/* AllocVecPooled(ULONG Size,ULONG Flags):
*
* Allocate a memory chunk from the main memory pool and
* remember its size.
*/
APTR __asm
AllocVecPooledLocal(register __d0 ULONG Size,register __d1 ULONG Flags,register __a0 ULONG ReturnAddr)
{
if(MemoryPool)
{
ObtainSemaphore(&MemorySemaphore);
if(FirewallPre)
{
struct FirewallInfo *Info;
ULONG FireSize;
ULONG RoundSize = (Size + 3) & ~3;
if(Smallest == -1)
Smallest = Size;
if(Largest == -1)
Largest = Size;
if(Size < Smallest)
Smallest = Size;
if(Size > Largest)
Largest = Size;
FireSize = sizeof(struct FirewallInfo) + FirewallPre + RoundSize + FirewallPost;
if(Info = (struct FirewallInfo *)AsmAllocPooled(MemoryPool,FireSize,SysBase))
{
ULONG *Data,Sum,*Thing;
WORD i;
Info -> Address = ((ULONG)Info) + sizeof(struct FirewallInfo) + FirewallPre;
Info -> TotalSize = FireSize;
Info -> ReturnAddress = ReturnAddr;
Info -> Size = Size;
Info -> FillByte = FillByte;
Info -> FirePre = (ULONG)&Info[1];
Info -> FirePost = Info -> FirePre + FirewallPre + RoundSize;
memset((APTR)(Info -> FirePre),FillByte,FirewallPre);
memset((APTR)(Info -> FirePost),FillByte,FirewallPost);
for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
Sum += Thing[i];
Info -> Checksum = ~Sum;
FillByte = (FillByte + 2) & 0xFF;
Data = (ULONG *)Info -> Address;
ReleaseSemaphore(&MemorySemaphore);
if(Flags & MEMF_CLEAR)
{
register ULONG *Memory = Data;
Size = RoundSize / sizeof(ULONG) - 1;
do
*Memory++ = 0;
while(Size--);
}
else
{
register ULONG *Memory = Data;
Size = RoundSize / sizeof(ULONG) - 1;
do
*Memory++ = 0xDEADBEEF;
while(Size--);
}
return((APTR)Data);
}
}
else
{
ULONG *Data;
Size = (Size + sizeof(ULONG) + 3) & ~3;
if(Data = (ULONG *)AsmAllocPooled(MemoryPool,Size,SysBase))
{
ReleaseSemaphore(&MemorySemaphore);
*Data++ = Size;
// Zero the chunk if necessary
if(Flags & MEMF_CLEAR)
{
register ULONG *Memory = Data;
Size = Size / sizeof(ULONG) - 2;
do
*Memory++ = 0;
while(Size--);
}
return((APTR)Data);
}
}
ReleaseSemaphore(&MemorySemaphore);
}
return(NULL);
}